package com.atguigu.controller;

import com.atguigu.exception.SleepUtils;
import io.swagger.annotations.Api;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Description
 * @Author: TT
 * @Date: 2022/7/28 17:46
 */
@RestController
@RequestMapping("product")
@Api(tags = "Redission管理接口")
public class RedissionControlller {
   @Autowired
   private RedissonClient redissonClient;

    /**
     * 测试普通锁
     * @return
     */
    @GetMapping("syn")
    public String synRedission(){
        RLock lock = redissonClient.getLock("anyLock");
        System.out.println(Thread.currentThread().getName());
       // 最常见的使用方法
        try {
            lock.lock();
            String task = UUID.randomUUID().toString().substring(6);
            SleepUtils.sleep(3);
            System.out.println(Thread.currentThread().getName()+"正在执行"+task+"任务");
            return Thread.currentThread().getName()+"正在执行"+task+"任务";
        } finally {
            lock.unlock();
        }
    }
    /**
     * 测试公平锁
     * @return
     */
    @GetMapping("safe")
    public String safeRedission() {

        RLock fairLock = redissonClient.getFairLock("anyLock");
        System.out.println(Thread.currentThread().getName());
        // 最常见的使用方法
        try {
            fairLock.lock();
            SleepUtils.sleep(2);
            System.out.println(Thread.currentThread().getName() + "当多个Redisson客户端线程同时请求加锁时，优先分配给先发出请求的线程");
            return "当多个Redisson客户端线程同时请求加锁时，优先分配给先发出请求的线程";
        } finally {
            fairLock.unlock();
        }

    }
        //Redisson内部提供了一个监控锁的看门狗
        @GetMapping("dog")
        public String  timeRedission(){
            RLock fairLock = redissonClient.getFairLock("lock");
            // 10秒钟以后自动解锁
          // 无需调用unlock方法手动解锁
            fairLock.lock(10, TimeUnit.SECONDS);

           // 尝试加锁，最多等待100秒，上锁以后10秒自动解锁]
            boolean res=false;
            try {
                 res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
                System.out.println(res+"加锁成功");

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Thread.currentThread().getName()+"正在执行"+"任务";
    }


    public String uuid=null;
    /**
     * 读写锁
     */
    //Redisson提供了 读写锁
    @GetMapping("read")
    public String readLock() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rwlock");
        RLock lock = readWriteLock.readLock();
        try {
            lock.lock();
            SleepUtils.sleep(10);
            return uuid;
        } finally {
            lock.unlock();
        }
    }
    @GetMapping("write")
    public String writeLock() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rwlock");
        RLock lock = readWriteLock.writeLock();
        try {
            lock.lock();
            SleepUtils.sleep(10);
            uuid=UUID.randomUUID().toString();
            System.out.println(Thread.currentThread().getName()+"正在写"+uuid);
        } finally {
            lock.unlock();
        }
        return "写了一个秘密"+uuid;
    }
    /**
     *  信号量（Semaphore）
     *  停车位
     */
    @GetMapping("park")
    public String park() throws InterruptedException {
        RSemaphore semaphore = redissonClient.getSemaphore("park-car");
        //信号量 减一
         semaphore.acquire(1);
         return Thread.currentThread().getName()+"驶进了车位";
    }
    @GetMapping("left")
    public String left() throws InterruptedException {
        RSemaphore semaphore = redissonClient.getSemaphore("park-car");
        //信号量 加一
        semaphore.release(1);
        return Thread.currentThread().getName()+"离开了车位";
    }
    /**
     * CountDownLatch
     */
    @GetMapping("leftClassRoom")
    public String leftClassRoom() throws InterruptedException {
        RCountDownLatch aClass = redissonClient.getCountDownLatch("class");
        //如果有人走了,数量减一
        aClass.countDown();
        System.out.println(Thread.currentThread().getName()+"离开了教室");
        return Thread.currentThread().getName()+"离开了教室";

    }
    @GetMapping("lockDoor")
    public String lockDoor() throws InterruptedException {
        RCountDownLatch aClass = redissonClient.getCountDownLatch("class");
        aClass.trySetCount(6);
        //如果有人走了,数量减一
        aClass.await();
        System.out.println(Thread.currentThread().getName()+"班长关上门离开了教室");
        return Thread.currentThread().getName()+"班长关上门离开了教室";
    }
}
